package pcgen.android.app;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.Window;
import android.webkit.WebView;
import android.widget.EditText;

import pcgen.ClassUtils;
import pcgen.android.Logger;
import pcgen.android.ResourceUtils;

public final class AppUtils 
{
	public static void alert(Activity activity, final int positiveId, final int negativeId, String title, String positiveTitle, String negativeTitle, String message, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(activity);
		
		try
    	{
			AlertDialog.Builder builder = new AlertDialog.Builder(activity);
			alert(activity, builder, positiveId, negativeId, title, positiveTitle, negativeTitle, message, onClickListenerPositive, onClickListenerNegative);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alert", tr);
    	}
    }
	
	public static void alert(Activity activity, AlertDialog.Builder builder, final int positiveId, final int negativeId, String title, String positiveTitle, String negativeTitle, String message, final DialogClickListenerHandler onClickListenerPositive, final DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(builder);
		
		try
    	{
			if (!StringUtils.isEmpty(message))
				builder.setMessage(message);
				
			builder
				.setCancelable(false)
				.setPositiveButton(positiveTitle, new DialogInterface.OnClickListener() 
				{
					public void onClick(DialogInterface dialog, int id) 
					{
						boolean cancel = false;
						if (onClickListenerPositive != null)
						{
							onClickListenerPositive.onClick(dialog, positiveId);
							cancel = onClickListenerPositive.Cancel;
						}
						if (!cancel)
						{
							dialog.dismiss();
							if (onClickListenerPositive != null)
								onClickListenerPositive.onAfterDismiss(dialog, id);
						}
					}       
				})
				.setNegativeButton(negativeTitle, new DialogInterface.OnClickListener() 
				{   
					public void onClick(DialogInterface dialog, int id) 
					{
						if (onClickListenerNegative != null)
							onClickListenerNegative.onClick(dialog, negativeId);

						dialog.dismiss();
						if (onClickListenerPositive != null)
							onClickListenerPositive.onAfterDismiss(dialog, id);
					}       
				});
			
			AlertDialog alert = builder.create();
			alert.setOwnerActivity(activity);
			if (!StringUtils.isEmpty(title))
				alert.setTitle(title);
			alert.show();
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alert", tr);
    	}
    }
	
	public static void alert(Activity activity, AlertDialog.Builder builder, String title, final DialogClickListenerHandler onClickListener)
    {
		try
		{
			String packageName = ClassUtils.getPackageName(activity.getClass());
			
	        alert(activity, builder, ID_ALERT_POSITIVE, title, ResourceUtils.getString(activity, "button_ok", packageName), onClickListener);
		}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alert", tr);
    	}
    }
	
	public static void alert(Activity activity, AlertDialog.Builder builder, final int buttonId, String title, String buttonTitle, final DialogClickListenerHandler onClickListener)
    {
		alert(activity, builder, buttonId, title, buttonTitle, onClickListener, true);
    }
	
	public static void alert(Activity activity, AlertDialog.Builder builder, final int buttonId, String title, String buttonTitle, final DialogClickListenerHandler onClickListener, boolean isPositiveButton)
    {
    	Validate.notNull(builder);
		
		try
    	{
			DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() 
			{
				public void onClick(DialogInterface dialog, int id) 
				{
					boolean cancel = false;
					if (onClickListener != null)
					{
						onClickListener.onClick(dialog, buttonId);
						cancel = onClickListener.Cancel;
					}

					if (!cancel)
					{
						dialog.dismiss();
						if (onClickListener != null)
							onClickListener.onAfterDismiss(dialog, id);
					}
				}       
			};
			
			builder.setCancelable(false);
			if (isPositiveButton)
				builder.setPositiveButton(buttonTitle, listener);
			else 
				builder.setNegativeButton(buttonTitle, listener);
			
			AlertDialog alert = builder.create();
			alert.setOwnerActivity(activity);
			if (!StringUtils.isEmpty(title))
				alert.setTitle(title);
			alert.show();
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alert", tr);
    	}
    }
	
    public static void alertCancel(Activity activity, AlertDialog.Builder builder, String title, DialogClickListenerHandler onClickListener)
    {
    	Validate.notNull(builder);
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		alert(activity, builder, ID_ALERT_POSITIVE, title, ResourceUtils.getString(activity, "button_cancel", packageName), onClickListener, false);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertOkCancel", tr);
    	}
    }
    
	public static void alertError(Activity activity, String message, final DialogClickListenerHandler onClickListener)
    {
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		AlertDialog.Builder builder = new AlertDialog.Builder(activity);
			builder.setMessage(message)
				.setCancelable(false)
				.setPositiveButton(ResourceUtils.getString(activity, "button_ok", packageName), new DialogInterface.OnClickListener() 
				{           
					public void onClick(DialogInterface dialog, int id) 
					{
						boolean cancel = false;
						if (onClickListener != null)
						{
							onClickListener.onClick(dialog, id);
							cancel = onClickListener.Cancel;
						}
						
						if (!cancel)
						{
							dialog.dismiss();
							if (onClickListener != null)
								onClickListener.onAfterDismiss(dialog, id);
						}
					}       
				});
			AlertDialog alert = builder.create();
			alert.setOwnerActivity(activity);
			alert.show();
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertError", tr);
    	}
    }
	
    public static void alertOkCancel(Activity activity, AlertDialog.Builder builder, String title, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	alertOkCancel(activity, builder, title, "", onClickListenerPositive, onClickListenerNegative);
    }
	
    public static void alertOkCancel(Activity activity, AlertDialog.Builder builder, String title, String message, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(builder);
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		alert(activity, builder, ID_ALERT_POSITIVE, ID_ALERT_NEGATIVE, title, ResourceUtils.getString(activity, "button_ok", packageName), ResourceUtils.getString(activity, "button_cancel", packageName), message, onClickListenerPositive, onClickListenerNegative);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertOkCancel", tr);
    	}
    }
	
    public static void alertOkCancel(Activity activity, String title, String message, DialogClickListenerHandler onClickListener)
    {
    	alertYesNo(activity, title, message, onClickListener, onClickListener);
    }
    
    public static void alertOkCancel(Activity activity, String title, String message, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		alert(activity, ID_ALERT_POSITIVE, ID_ALERT_NEGATIVE, title, ResourceUtils.getString(activity, "button_ok", packageName), ResourceUtils.getString(activity, "button_cancel", packageName), message, onClickListenerPositive, onClickListenerNegative);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertOkCancel", tr);
    	}
    }
	
    public static void alertOkCancelWithAsset(Activity activity, String title, String asset, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
			
	        WebView htmlWebView = new WebView(activity);
	        htmlWebView.loadUrl("file:///android_asset/" + asset);
	        
	        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
	        builder
	        	.setView(htmlWebView);
	        
	    	alert(activity, builder, ID_ALERT_POSITIVE, ID_ALERT_NEGATIVE, title, ResourceUtils.getString(activity, "button_ok", packageName), ResourceUtils.getString(activity, "button_cancel", packageName), "", onClickListenerPositive, onClickListenerNegative);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertOkCancelWithAsset", tr);
    	}
    }
	
    public static void alertText(Activity activity, String title, String message, DialogClickListenerHandler onClickListener)
    {
    	alertText(activity, title, message, onClickListener, onClickListener);
    }
    
    public static void alertText(final Activity activity, String title, String message, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
			AlertDialog.Builder builder = new AlertDialog.Builder(activity);
			
			EditText input = new EditText(activity);
			builder.setView(input);
			onClickListenerPositive.setTag(input);
			
			alert(activity, builder, ID_ALERT_POSITIVE, ID_ALERT_NEGATIVE, title, ResourceUtils.getString(activity, "button_ok", packageName), ResourceUtils.getString(activity, "button_cancel", packageName), message, onClickListenerPositive, onClickListenerNegative);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertText", tr);
    	}
    }
	
    public static void alertWithAsset(Activity activity, String title, String asset, DialogClickListenerHandler onClickListener)
    {
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
			
	        WebView htmlWebView = new WebView(activity);
	        htmlWebView.loadUrl("file:///android_asset/" + asset);
	        
	        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
	        builder.setView(htmlWebView);
	        
	    	alert(activity, builder, ID_ALERT_POSITIVE, title, ResourceUtils.getString(activity, "button_ok", packageName), onClickListener, true);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertWithAsset", tr);
    	}
    }
	
    public static void alertYesNo(Activity activity, String title, String message, DialogClickListenerHandler onClickListener)
    {
    	alertYesNo(activity, title, message, onClickListener, onClickListener);
    }
    
    public static void alertYesNo(Activity activity, String title, String message, DialogClickListenerHandler onClickListenerPositive, DialogClickListenerHandler onClickListenerNegative)
    {
    	Validate.notNull(activity);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		alert(activity, ID_ALERT_POSITIVE, ID_ALERT_NEGATIVE, title, ResourceUtils.getString(activity, "button_yes", packageName), ResourceUtils.getString(activity, "button_no", packageName), message, onClickListenerPositive, onClickListenerNegative);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "alertYesNo", tr);
    	}
    }
    
    public static void confirm(Activity activity, int confirmMessageId, final DialogClickListenerHandler onClickListener)
    {
    	Validate.notNull(activity);
    	
    	try
    	{
			confirm(activity, ResourceUtils.getString(activity, confirmMessageId), onClickListener);
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "confirm", tr);
    	}
			
    }
    	
    public static void confirm(final Activity activity, String confirmMessage, final DialogClickListenerHandler onClickListener)
    {
    	Validate.notNull(activity);
    	Validate.notNull(onClickListener);
		
		try
    	{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		AlertDialog.Builder builder = new AlertDialog.Builder(activity);
			builder.setMessage(confirmMessage)
				.setCancelable(false)
				.setPositiveButton(ResourceUtils.getString(activity, "button_ok", packageName), new DialogInterface.OnClickListener() 
				{           
					public void onClick(DialogInterface dialog, int id) 
					{               
						boolean cancel = false;
						if (onClickListener != null)
						{
							onClickListener.onClick(dialog, ID_ALERT_POSITIVE);
							cancel = onClickListener.Cancel;
						}

						if (!cancel)
						{
							dialog.dismiss();
							if (onClickListener != null)
								onClickListener.onAfterDismiss(dialog, id);
						}
					}       
				})
				.setNegativeButton(ResourceUtils.getString(activity, "button_cancel", packageName), new DialogInterface.OnClickListener() 
				{           
					public void onClick(DialogInterface dialog, int id) 
					{               
						dialog.cancel();              
					}       
				});
			AlertDialog alert = builder.create();
			alert.setOwnerActivity(activity);
			alert.show();
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "confirm", tr);
    	}
    }
	
	public static void exit(final Activity activity)
    {
    	exit(activity, "", null, true);
    }
	
    public static void exit(final Activity activity, DialogClickListenerHandler onClickListener)
    {
    	exit(activity, "", onClickListener, true);
    }
	
    public static void exit(final Activity activity, boolean confirm)
    {
    	exit(activity, "", null, confirm);
    }
	
    public static void exit(final Activity activity, DialogClickListenerHandler onClickListener, boolean confirm)
    {
    	exit(activity, "", onClickListener, confirm);
    }
	
    public static void exit(final Activity activity, String message)
    {
    	exit(activity, message, null, true);
    }
	
    public static void exit(final Activity activity, String message, DialogClickListenerHandler onClickListener)
    {
    	exit(activity, message, onClickListener, true);
    }
    
    public static void exit(final Activity activity, String message, final DialogClickListenerHandler onClickListener, boolean confirm)
    {
    	Validate.notNull(activity);
		
		try
    	{
			if (confirm)
			{
	    		String packageName = ClassUtils.getPackageName(activity.getClass());
	    		if (StringUtils.isEmpty(message))
	    			message = ResourceUtils.getString(activity, "confirm_exit", packageName);
	    		
	    		AlertDialog.Builder builder = new AlertDialog.Builder(activity);
	    		builder.setMessage(message)
					.setCancelable(false)
					.setPositiveButton(ResourceUtils.getString(activity, "button_ok", packageName), new DialogInterface.OnClickListener() 
					{           
						public void onClick(DialogInterface dialog, int id) 
						{               
							dialog.dismiss();
							if (onClickListener != null)
								onClickListener.onClick(dialog, id);
							activity.finish();
						}       
					})
					.setNegativeButton(ResourceUtils.getString(activity, "button_cancel", packageName), new DialogInterface.OnClickListener() 
					{           
						public void onClick(DialogInterface dialog, int id) 
						{               
							dialog.cancel();              
						}       
					});
				AlertDialog alert = builder.create();
				alert.setOwnerActivity(activity);
				alert.show();
	    	}
			else
				activity.finish();
    	}
    	catch(Throwable tr)
    	{
    		Logger.e(TAG, "exit", tr);
    	}
    }
	
 // FIXME: this method currently doesn't work as advertised.  See droidfu for more info
    public static int getWindowFeatures(Activity activity) 
    {
        Window window = activity.getWindow();
        if (window == null)
            return 0;
        
        try 
        {
            // Method m =
            // activity.getWindow().getClass().getMethod("getFeatures");
            // Method[] m = window.getClass().getMethods();
            // m.setAccessible(true);
            // return (Integer) m.invoke(window);
            return 0;
        } 
        catch (Exception e)
        {
            return 0;
        }
    }

    public static int getLayoutIdByName(Activity activity, String name)
	{
		Validate.notNull(activity);
		Validate.notEmpty(name);
		
		try
		{
			String packageName = ClassUtils.getPackageName(activity.getClass());
    		int id = ResourceUtils.getLayoutIdentifier(activity, name, packageName);
    		return id;
		}
		catch (Throwable tr)
		{
			Logger.e(TAG, "getLayoutIdByName", tr);
		}
    	
    	return -1;
	}

    public static boolean inflateMenu(Activity activity, Menu menu, int id)
	{
		Validate.notNull(activity);
		Validate.notNull(menu);
		
		try
		{
			MenuInflater inflater = activity.getMenuInflater();
			inflater.inflate(id, menu);
			return true;
		}
		catch (Throwable tr)
		{
			Logger.e(TAG, "inflateMenu", tr);
		}
    	
    	return false;
	}

    public static boolean isApplicationBroughtToBackground(Context context) 
    {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
        if (!taskInfo.isEmpty()) 
        {
            ComponentName topActivity = taskInfo.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName()))
                return true;
        }

        return false;
    }
    
    public static final int ID_ALERT_NEGATIVE = 1001;
	public static final int ID_ALERT_POSITIVE = 1000;
	
    private static final String TAG = AppUtils.class.getSimpleName();
}
